package com.inkyi.assistant.app.todolist.event;

import com.inkyi.assistant.app.todolist.TodoContext;
import com.inkyi.assistant.app.todolist.TodoServiceApi;
import com.inkyi.assistant.app.todolist.left.GroupItem;
import com.inkyi.assistant.app.todolist.table.TodoItem;
import com.inkyi.framework.common.event.InkActionEvent;
import com.inkyi.framework.common.event.InkActionListener;
import com.inkyi.framework.common.utils.CastUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class TodoEventListener implements InkActionListener {

    private static Logger logger = LoggerFactory.getLogger(TodoEventListener.class);

    private void handleGroup(InkActionEvent event) {
        if (TodoEvent.TYPE_GROUP_NEW.equals(event.getType())) {
            TodoGroupDTO data = new TodoGroupDTO();
            data.setTitle("新建分组");
            TodoServiceApi.groupSave(data);
            SwingUtilities.invokeLater(() -> {
                GroupItem item = new GroupItem(data.getId(), data.getTitle());
                TodoContext.getTodoLeftPanel().getGroupListModel().addOrUpdate(item);
            });
        } else if (TodoEvent.TYPE_GROUP_DEL.equals(event.getType())) {
            GroupItem item = TodoContext.getTodoLeftPanel().getGroupList().getSelectedValue();
            TodoServiceApi.groupDelete((Long) item.getId());
            SwingUtilities.invokeLater(() -> {
                TodoContext.getTodoLeftPanel().getGroupListModel().delElement(item);
            });
        } else if (TodoEvent.TYPE_GROUP_UPDATE.equals(event.getType())) {
            GroupItem item = CastUtils.cast(event.getData(), GroupItem.class);
            TodoGroupDTO data = new TodoGroupDTO();
            data.setId((Long) item.getId());
            data.setTitle(item.getTitle());
            data.setUpdateTime(LocalDateTime.now());
            TodoServiceApi.groupSave(data);
            SwingUtilities.invokeLater(() -> {
                GroupItem newItem = new GroupItem(data.getId(), data.getTitle());
                TodoContext.getTodoLeftPanel().getGroupListModel().addOrUpdate(newItem);
            });
        } else if (TodoEvent.TYPE_LOAD_INIT_DATA.equals(event.getType())) {
            TodoServiceApi.checkInitData();
            List<GroupItem> groupItems = TodoServiceApi.groupItemList("");
            SwingUtilities.invokeLater(() -> {
                for (GroupItem item : groupItems) {
                    TodoContext.getTodoLeftPanel().getGroupListModel().addElement(item);
                }
            });
        }
    }

    private void handleRecord(InkActionEvent event) {
        if (TodoEvent.TYPE_RECORD_LIST.equals(event.getType())) {
            List<TodoItem> todoItems = TodoServiceApi.todoItemList(event.getParams());
            String sourceType = (String) event.getParams().get("sourceGroup");
            SwingUtilities.invokeLater(() -> {
                if (Objects.equals(sourceType, "fixed")) {
                    TodoContext.getTodoLeftPanel().getGroupList().clearSelection();
                } else if (Objects.equals(sourceType, "group")) {
                    TodoContext.getTodoLeftPanel().getFixedList().clearSelection();
                }
                TodoContext.getTodoRightMainContent().clearTodoItems();
                TodoContext.getTodoRightMainContent().addTodoItems(todoItems);
            });
        } else if (TodoEvent.TYPE_RECORD_NEW.equals(event.getType())) {
            Map<String, Object> params = event.getParams();
            String title = (String) params.get("title");
            LocalDate todoTime = (LocalDate) params.get("todoTime");
            Long groupId = 0L;
            GroupItem group = TodoContext.getTodoLeftPanel().getGroupList().getSelectedValue();
            if (group != null) {
                groupId = (Long) group.getId();
            }
            TodoRecordDTO data = new TodoRecordDTO();
            data.setTitle(title);
            data.setTodoTime(todoTime);
            data.setGroupId(groupId);
            data.setFinish(Boolean.FALSE);
            TodoServiceApi.recordSave(data);
            SwingUtilities.invokeLater(() -> {
                TodoItem currItem = new TodoItem(data.getId(), data.getFinish(), data.getTitle());
                TodoContext.getTodoRightMainContent().addTodoItems(List.of(currItem));
                TodoContext.getTodoRightMainContent().getTitleField().setText("");
            });
        } else if (TodoEvent.TYPE_RECORD_DEL.equals(event.getType())) {
            Long id = (Long) event.getData();
            TodoServiceApi.recordDelete(id);
            SwingUtilities.invokeLater(() -> {
                List<TodoItem> todoItems = TodoContext.getTodoRightMainContent().findTodoSelection();
                TodoContext.getTodoRightMainContent().delTodoItems(todoItems);
            });
        } else if (TodoEvent.TYPE_RECORD_SAVE.equals(event.getType())) {
            TodoRecordDTO data = (TodoRecordDTO) event.getData();
            TodoServiceApi.recordSave(data);
        } else if (TodoEvent.TYPE_RECORD_FINISH.equals(event.getType())) {
            TodoRecordDTO data = (TodoRecordDTO) event.getData();
            TodoServiceApi.recordSave(data);
            SwingUtilities.invokeLater(() -> {
                TodoItem currItem = new TodoItem(data.getId(), data.getFinish(), data.getTitle());
                TodoContext.getTodoRightMainContent().updateFinish(currItem);
            });
        } else if (TodoEvent.TYPE_RECORD_SHOW.equals(event.getType())) {
            TodoItem data = (TodoItem) event.getData();
            TodoRecordDTO record = TodoServiceApi.findRecordOne(data.getId());
            List<TodoGroupDTO> groupList = TodoServiceApi.groupDtoList();
            SwingUtilities.invokeLater(() -> {
                TodoContext.getTodoRightDrawerContent().setInfo(record, groupList);
                TodoContext.getTodoRightPanel().visibleDrawer(true);
            });
        }
    }

    @Override
    public void actionPerformed(InkActionEvent event) {
        logger.info("接收到待办事件监听:" + event);
        // 处理分组
        handleGroup(event);
        // 处理记录
        handleRecord(event);

    }
}
